/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is mkiosk_biblio. Modified In Coral IE Tab and now in Mkiosk
 *
 * The Initial Developer of the Original Code is yuoo2k <yuoo2k@gmail.com> and Modified by quaful <quaful@msn.com>. 
 * Modified by smarca <smarca@gmail.com>. 
  *
 * Portions created by the Initial Developer are Copyright (C) 2006-2008
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** */
 
 
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is mkiosk_biblio. Modified In Coral IE Tab.
 *
 * The Initial Developer of the Original Code is yuoo2k <yuoo2k@gmail.com>.
 * Modified by quaful <quaful@msn.com>.
 *
 * Portions created by the Initial Developer are Copyright (C) 2006-2008
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * ***** END LICENSE BLOCK ***** */
 
function mkiosk_biblio() {}

		mkiosk_biblio.prototype = {
			IExploreExePath: "",
		   
			mkiosk_biblio_SYNC_COOKIES: 1,
			mkiosk_biblio_SYNC_USER_AGENT: 2,
			mkiosk_biblio_AUTO_SWITCH_BACK: 4,
		}

		mkiosk_biblio.prototype.getPrefRuleList = function() {
			var s = this.getStrPref("coral.mkiosk_biblio.rulelist", null);
			if(s) {
				return JSON.parse(s);
			}
			else {
				return null;
			}
		}

		mkiosk_biblio.prototype.getPrefFilterListFromOldmkiosk_biblio = function() {
		   var s = this.getStrPref("mkiosk_biblio.filterlist", null);
		   return (s ? s.split(" ") : "");
		}

		mkiosk_biblio.prototype.addFilterRule = function(rule) {
			var pos = rule.indexOf(',');
			if ( -1 == pos ) return 0;
			var flags = parseInt(rule.substr(0,pos));
			var ruleStr = rule.substr(pos+1);
			var rulesListChilds = document.getElementById('rulesListChilds');
			
			// Checking whether the rule already exists
			var bFound = false;
			for ( var i = 0; i < rulesListChilds.childNodes.length; i++ ) {
				var child = rulesListChilds.childNodes[i];
				if ( child.firstChild.firstChild.getAttribute('label') == ruleStr )
				{
					bFound = true;
					break;
				}
			}
			
			if (!bFound) {
				var item = document.createElement('treeitem');
				var row = document.createElement('treerow');
				var c1 = document.createElement('treecell');
				c1.setAttribute('label', ruleStr);
				var c2 = document.createElement('treecell');
				c2.setAttribute('value', (flags & 0x8000) == 0);	// The highest bit == 1 means disabled
				var c3 = document.createElement('treecell');
				c3.setAttribute('value', (flags & this.mkiosk_biblio_SYNC_COOKIES) != 0);
				var c4 = document.createElement('treecell');
				c4.setAttribute('value', (flags & this.mkiosk_biblio_SYNC_USER_AGENT) != 0);
				var c5 = document.createElement('treecell');
				c5.setAttribute('value', (flags & this.mkiosk_biblio_AUTO_SWITCH_BACK) != 0);
				row.appendChild(c1);
				row.appendChild(c2);
				row.appendChild(c3);
				row.appendChild(c4);
				row.appendChild(c5);
				item.appendChild(row);
				rulesListChilds.appendChild(item);
			}
			
			return (rulesListChilds.childNodes.length-1);
		}

		mkiosk_biblio.prototype.initDialog = function() {
		   // get iexplore.exe path
		   this.IExploreExePath = mkiosk_biblioExtApp.getIExploreExePath();

			////////////////////////////////////////////////////////////////
			// rules
			// Firstly we'll clear the existing contents 
			var rules = document.getElementById('rulesListChilds');
			while (rules.hasChildNodes()) rules.removeChild(rules.firstChild);
			// Then we'll fill the contents with rules from preference
			var ruleList = this.getPrefRuleList();
			if ( ruleList ) {
				for (var i = 0; i < ruleList.length; i++) {
					if (ruleList[i]) {
						this.addFilterRule(ruleList[i]);
					}
				}
			}
			////////////////////////////////////////////////////////////////
		   
		   //general
		   document.getElementById('toolsmenu').checked = this.getBoolPref("coral.mkiosk_biblio.toolsmenu", true);
		   document.getElementById('toolsmenu.icon').checked = this.getBoolPref("coral.mkiosk_biblio.toolsmenu.icon", false);
		   document.getElementById('statusbar').checked = this.getBoolPref("coral.mkiosk_biblio.statusbar", true);
		   document.getElementById('handleurl').checked = this.getBoolPref("coral.mkiosk_biblio.handleUrlBar", false);
		   document.getElementById('alwaysnew').checked = this.getBoolPref("coral.mkiosk_biblio.alwaysNewTab", false);
		   document.getElementById('focustab').checked  = this.getBoolPref("coral.mkiosk_biblio.focustab", true);
		   
			var mode = this.getStrPref("coral.mkiosk_biblio.mode", "");
			var firstRun = mode.length==0;
			gmkiosk_biblio.setAttributeHidden(document.getElementById('switchgrp'), firstRun);
			gmkiosk_biblio.setAttributeHidden(document.getElementById('firstrunDescr'), !firstRun);

			var isClassicMode = mode!="advanced";
			var cookieSync = (!isClassicMode) && this.getBoolPref("coral.mkiosk_biblio.cookieSync", false);
			document.getElementById('adblock').checked = (!isClassicMode) && this.getBoolPref("coral.mkiosk_biblio.adblock", false);
			document.getElementById('cookieSync').checked = cookieSync;
			document.getElementById('showprompt').checked  = cookieSync && this.getBoolPref("coral.mkiosk_biblio.showprompt", true);
			document.getElementById('modegrp').selectedIndex = isClassicMode ? 0:1;
			document.getElementById('adblock').disabled = isClassicMode;
			document.getElementById('cookieSync').disabled = isClassicMode;
			document.getElementById('showprompt').disabled = isClassicMode || !cookieSync;

		   //context
		   document.getElementById('pagelink.embed').checked = this.getBoolPref("coral.mkiosk_biblio.pagelink", true);
		   document.getElementById('tabsmenu.embed').checked = this.getBoolPref("coral.mkiosk_biblio.tabsmenu", true);
		   document.getElementById('bookmark.embed').checked = this.getBoolPref("coral.mkiosk_biblio.bookmark", true);

		   document.getElementById('pagelink.extapp').checked = this.getBoolPref("coral.mkiosk_biblio.pagelink.extapp", true);
		   document.getElementById('tabsmenu.extapp').checked = this.getBoolPref("coral.mkiosk_biblio.tabsmenu.extapp", true);
		   document.getElementById('bookmark.extapp').checked = this.getBoolPref("coral.mkiosk_biblio.bookmark.extapp", true);

		   document.getElementById('pagelink.icon').checked = this.getBoolPref("coral.mkiosk_biblio.icon.pagelink", false);
		   document.getElementById('tabsmenu.icon').checked = this.getBoolPref("coral.mkiosk_biblio.icon.tabsmenu", false);
		   document.getElementById('bookmark.icon').checked = this.getBoolPref("coral.mkiosk_biblio.icon.bookmark", false);

		   //external
		   var path = this.getStrPref("coral.mkiosk_biblio.extAppPath", "");
		   document.getElementById('pathbox').value = (path == "" ? this.IExploreExePath : path);
		   document.getElementById('parambox').value = this.getStrPref("coral.mkiosk_biblio.extAppParam", "%1");
		   document.getElementById('ctrlclick').checked = this.getBoolPref("coral.mkiosk_biblio.ctrlclick", true);

		   //fill urlbox
		   var newurl = (window.arguments ? window.arguments[0] : ""); //get CurrentTab's URL
		   document.getElementById('urlbox').value = ( this.startsWith(newurl,"about:") ? "" : newurl);
		   document.getElementById('urlbox').select();
		   
		   //updateStatus
		   this.updateDialogPositions();
		   this.updateDialogAllStatus();
		   this.updateApplyButton(false);
		   
			if (window.arguments && window.arguments.length > 2 && window.arguments[2]) {
				document.getElementById("dlgTab").selectedIndex = window.arguments[2];
			}
		}

		mkiosk_biblio.prototype.updateApplyButton = function(e) {
		   document.getElementById("myExtra1").disabled = !e;
		}

		mkiosk_biblio.prototype.updateCheckBox = function(e) {
			if ( e.target && e.target.id == "cookieSync" )
			{
				var cookieSync = e.target.checked;
				var elm = document.getElementById('showprompt');
				elm.disabled = ! cookieSync;
				elm.checked  = cookieSync && gmkiosk_biblio.getBoolPref("coral.mkiosk_biblio.showprompt", true);
				
				if (gmkiosk_biblio.getStrPref("coral.mkiosk_biblio.mode", "").length > 0) {
					gmkiosk_biblio.setAttributeHidden(document.getElementById('restartPrompt'), false);
				}
			}
			gmkiosk_biblio.updateApplyButton(e);
		}

		mkiosk_biblio.prototype.updateRadio = function(e) {
			var isClassicMode = document.getElementById('classicMode').selected;
			
			var c1 = document.getElementById('adblock');
			c1.disabled = isClassicMode;
			c1.checked = (!isClassicMode) && gmkiosk_biblio.getBoolPref("coral.mkiosk_biblio.adblock", false);
			
			var cookieSync = (!isClassicMode) && gmkiosk_biblio.getBoolPref("coral.mkiosk_biblio.cookieSync", false);
			
			var c2 = document.getElementById('cookieSync');
			c2.disabled = isClassicMode;
			c2.checked = cookieSync;
			
			var c3 = document.getElementById('showprompt');
			c3.disabled = isClassicMode || !cookieSync;
			c3.checked  = cookieSync && gmkiosk_biblio.getBoolPref("coral.mkiosk_biblio.showprompt", true);
			
			if (gmkiosk_biblio.getStrPref("coral.mkiosk_biblio.mode", "").length > 0)
			{
				gmkiosk_biblio.setAttributeHidden(document.getElementById('restartPrompt'), false);
			}
			gmkiosk_biblio.updateApplyButton(e);
		}

		mkiosk_biblio.prototype.init = function() {
		   this.initDialog();
		   this.addEventListenerByTagName("checkbox", "CheckboxStateChange", this.updateCheckBox);
		   this.addEventListenerByTagName("radio", "RadioStateChange", this.updateRadio);
		   this.addEventListener("rulesListChilds", "DOMAttrModified", this.updateApplyButton);
		   this.addEventListener("rulesListChilds", "DOMNodeInserted", this.updateApplyButton);
		   this.addEventListener("rulesListChilds", "DOMNodeRemoved", this.updateApplyButton);
		   this.addEventListener("parambox", "input", this.updateApplyButton);
		   this.addEventListener("toolsmenu", "command", this.updateToolsMenuStatus);
		}

		mkiosk_biblio.prototype.destory = function() {
		   this.removeEventListenerByTagName("checkbox", "command", this.updateApplyButton);
		   this.removeEventListener("rulesListChilds", "DOMAttrModified", this.updateApplyButton);
		   this.removeEventListener("rulesListChilds", "DOMNodeInserted", this.updateApplyButton);
		   this.removeEventListener("rulesListChilds", "DOMNodeRemoved", this.updateApplyButton);
		   this.removeEventListener("parambox", "input", this.updateApplyButton);
		   this.removeEventListener("toolsmenu", "command", this.updateToolsMenuStatus);
		}

		mkiosk_biblio.prototype.updateInterface = function() {
		   var statusbar = this.getBoolPref("coral.mkiosk_biblio.statusbar", true);
		   var icon = (window.arguments ? window.arguments[1] : null); //get status-bar icon handle
		   if (icon) this.setAttributeHidden(icon, !statusbar);
		}

		mkiosk_biblio.prototype.setOptions = function() {
		   //filter
		   this.setBoolPref("coral.mkiosk_biblio.filter", true);
		   this.setStrPref("coral.mkiosk_biblio.rulelist", this.getRuleListString());

		   //general
		   var toolsmenu = document.getElementById('toolsmenu').checked;
		   this.setBoolPref("coral.mkiosk_biblio.toolsmenu", toolsmenu);
		   this.setBoolPref("coral.mkiosk_biblio.toolsmenu.icon", document.getElementById('toolsmenu.icon').checked);

		   var statusbar = document.getElementById('statusbar').checked;
		   this.setBoolPref("coral.mkiosk_biblio.statusbar", statusbar);

		   this.setBoolPref("coral.mkiosk_biblio.handleUrlBar", document.getElementById('handleurl').checked);
		   this.setBoolPref("coral.mkiosk_biblio.alwaysNewTab", document.getElementById('alwaysnew').checked);
		   this.setBoolPref("coral.mkiosk_biblio.focustab", document.getElementById('focustab').checked);
			
			if (document.getElementById('classicMode').selected)
				this.setStrPref("coral.mkiosk_biblio.mode","classic");
			else {
				this.setStrPref("coral.mkiosk_biblio.mode","advanced");
				this.setBoolPref("coral.mkiosk_biblio.adblock", document.getElementById('adblock').checked);
				
				var cookieSync = document.getElementById('cookieSync').checked;
				this.setBoolPref("coral.mkiosk_biblio.cookieSync", cookieSync);
				if ( cookieSync ) this.setBoolPref("coral.mkiosk_biblio.showprompt", document.getElementById('showprompt').checked);
			}


		   //context (mkiosk_biblio)
		   this.setBoolPref("coral.mkiosk_biblio.pagelink", document.getElementById('pagelink.embed').checked);
		   this.setBoolPref("coral.mkiosk_biblio.tabsmenu", document.getElementById('tabsmenu.embed').checked);
		   this.setBoolPref("coral.mkiosk_biblio.bookmark", document.getElementById('bookmark.embed').checked);

		   //context (extapp)
		   this.setBoolPref("coral.mkiosk_biblio.pagelink.extapp", document.getElementById('pagelink.extapp').checked);
		   this.setBoolPref("coral.mkiosk_biblio.tabsmenu.extapp", document.getElementById('tabsmenu.extapp').checked);
		   this.setBoolPref("coral.mkiosk_biblio.bookmark.extapp", document.getElementById('bookmark.extapp').checked);

		   //showicon
		   this.setBoolPref("coral.mkiosk_biblio.icon.pagelink", document.getElementById('pagelink.icon').checked);
		   this.setBoolPref("coral.mkiosk_biblio.icon.tabsmenu", document.getElementById('tabsmenu.icon').checked);
		   this.setBoolPref("coral.mkiosk_biblio.icon.bookmark", document.getElementById('bookmark.icon').checked);

		   //external
		   var path = document.getElementById('pathbox').value;
		   this.setStrPref("coral.mkiosk_biblio.extAppPath", (path == this.IExploreExePath ? "" : path));

		   var param = document.getElementById('parambox').value;
		   this.setStrPref("coral.mkiosk_biblio.extAppParam", this.trim(param).split(/\s+/).join(" "));

		   this.setBoolPref("coral.mkiosk_biblio.ctrlclick", document.getElementById('ctrlclick').checked);

		   //update UI
		   this.updateApplyButton(false);
		   this.updateInterface();
		}

		mkiosk_biblio.prototype.setAttributeHidden = function(obj, isHidden) {
			if (!obj) return;
			if (isHidden){
				obj.setAttribute("hidden", true);
			}else{
				obj.removeAttribute("hidden");
			}
		}

		mkiosk_biblio.prototype.getRuleListString = function() {
			var list = [];
			var rules = document.getElementById('rulesList');
			var count = rules.view.rowCount;
			for (var i=0; i<count; i++) {
				var rule = rules.view.getCellText(i, rules.columns['col-rules']);
				if(rule!="")
				{
					var flags = 0;
					
					if(rules.view.getCellValue(i, rules.columns['col-enabled'])=="false") flags |= 0x8000;			// The highest bit == 1 means disabled
					if(rules.view.getCellValue(i, rules.columns['col-sync-cookies'])=="true") flags |= this.mkiosk_biblio_SYNC_COOKIES;
					if(rules.view.getCellValue(i, rules.columns['col-sync-useragent'])=="true") flags |= this.mkiosk_biblio_SYNC_USER_AGENT;
					if(rules.view.getCellValue(i, rules.columns['col-switchback'])=="true") flags |= this.mkiosk_biblio_AUTO_SWITCH_BACK;
					
					list.push(flags+","+rule);
				}
			}
			return JSON.stringify(list);
		}

		mkiosk_biblio.prototype.updateToolsMenuStatus = function() {
		   document.getElementById("toolsmenu.icon").disabled = !document.getElementById("toolsmenu").checked;
		}

		mkiosk_biblio.prototype.updateAddButtonStatus = function() {
		   var addbtn = document.getElementById('addbtn');
		   var urlbox = document.getElementById('urlbox');
		   addbtn.disabled = (this.trim(urlbox.value).length < 1);
		}

		mkiosk_biblio.prototype.updateDialogAllStatus = function() {
		   this.updateAddButtonStatus();
		   this.updateToolsMenuStatus();
		}

		mkiosk_biblio.prototype.updateDialogPositions = function() {
		   var em = [document.getElementById('tabsmenu.embed'),
					 document.getElementById('pagelink.embed'),
					 document.getElementById('bookmark.embed')]
		   var ex = [document.getElementById('tabsmenu.extapp'),
					 document.getElementById('pagelink.extapp'),
					 document.getElementById('bookmark.extapp')]
		   var emMax = Math.max(em[0].boxObject.width, em[1].boxObject.width, em[2].boxObject.width);
		   var exMax = Math.max(ex[0].boxObject.width, ex[1].boxObject.width, ex[2].boxObject.width);
		   for (var i=0 ; i<em.length ; i++) em[i].width = emMax;
		   for (var i=0 ; i<ex.length ; i++) ex[i].width = exMax;
		}

		mkiosk_biblio.prototype.findRule = function(value) {
		   var ruleList = document.getElementById('rulesList');
		   var count = ruleList.view.rowCount;
		   for (var i=0; i<count; i++) {
			  var rule = ruleList.view.getCellText(i, ruleList.columns['col-rules']);
			  if (rule == value) return i;
		   }
		   return -1;
		}

		mkiosk_biblio.prototype.addNewURL = function() {
		   var ruleList = document.getElementById('rulesList');
		   var urlbox = document.getElementById('urlbox');
		   var rule = this.trim(urlbox.value);
		   if (rule != "") {
			  if ((rule != "about:blank") && (rule.indexOf("://") < 0)) {
				 rule = (/^[A-Za-z]:/.test(rule) ? "file:///"+rule.replace(/\\/g,"/") : rule);
				 if (/^file:\/\/.*/.test(rule)) rule = encodeURI(rule);
			  }
			  if (!/^\/(.*)\/$/.exec(rule)) rule = rule.replace(/\/$/, "/*");
			  rule = rule.replace(/\s/g, "%20");
			  var idx = this.findRule(rule);
			  if (idx == -1) {
				idx = this.addFilterRule("0,"+rule);
				
				urlbox.value = "";
			  }
			  ruleList.view.selection.select(idx);
			  ruleList.boxObject.ensureRowIsVisible(idx);
		   }
		   ruleList.focus();
		   this.updateAddButtonStatus();
		}

		mkiosk_biblio.prototype.delSelected = function() {
			var ruleList = document.getElementById('rulesList');
			if (ruleList) {
				var rules = document.getElementById('rulesListChilds');
				if (ruleList.view.selection.count > 0) {
					for (var i=rules.childNodes.length-1 ; i>=0 ; i--) {
						if (ruleList.view.selection.isSelected(i))
							rules.removeChild(rules.childNodes[i]);
					}
				}
			}
		}

		mkiosk_biblio.prototype.onClickFilterList = function(e) {
		   var ruleList = document.getElementById('rulesList');
		   if (!ruleList.disabled && e.button == 0 && e.detail >= 2) {
			  if (ruleList.view.selection.count == 1) {
				 var urlbox = document.getElementById('urlbox');
				 urlbox.value = ruleList.view.getCellText(ruleList.currentIndex, ruleList.columns['col-rules']);
				 urlbox.select();
				 this.updateAddButtonStatus();
			  }
		   }
		}

		mkiosk_biblio.prototype.modifyTextBoxValue = function(textboxId, newValue) {
		   var box = document.getElementById(textboxId);
		   if (box.value != newValue) {
			  box.value = newValue;
			  this.updateApplyButton(true);
		   }
		}

		mkiosk_biblio.prototype.browseAppPath = function() {
		   const nsIFilePicker = Components.interfaces.nsIFilePicker;
		   var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
		   fp.init(window, null, nsIFilePicker.modeOpen);
		   fp.appendFilters(nsIFilePicker.filterApps);
		   fp.appendFilters(nsIFilePicker.filterAll);
		   var rv = fp.show();
		   if (rv == nsIFilePicker.returnOK) {
			  this.modifyTextBoxValue("pathbox", fp.file.target);
		   }
		}

		mkiosk_biblio.prototype.resetAppPath = function() {
		   this.modifyTextBoxValue("pathbox", this.IExploreExePath);
		   this.modifyTextBoxValue("parambox", "%1");
		}

		mkiosk_biblio.prototype.saveToFile = function(aList) {
		   var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker);
		   var stream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
		   var converter = Components.classes["@mozilla.org/intl/converter-output-stream;1"].createInstance(Components.interfaces.nsIConverterOutputStream);

		   fp.init(window, null, fp.modeSave);
		   fp.defaultExtension = "txt";
		   fp.defaultString = "IE Tab Plus Rules";
		   fp.appendFilters(fp.filterText);

		   if (fp.show() != fp.returnCancel) {
			  try {
				 if (fp.file.exists()) fp.file.remove(true);
				 fp.file.create(fp.file.NORMAL_FILE_TYPE, 0666);
				 stream.init(fp.file, 0x02, 0x200, null);
				 converter.init(stream, "UTF-8", 0, 0x0000);

				 for (var i = 0; i < aList.length ; i++) {
					aList[i] = aList[i] + "\n";
					converter.writeString(aList[i]);
				 }
			  } finally {
				 converter.close();
				 stream.close();
			  }
		   }
		}

		mkiosk_biblio.prototype.loadFromFile = function() {
		   var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(Components.interfaces.nsIFilePicker);
		   var stream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
		   var converter = Components.classes["@mozilla.org/intl/converter-input-stream;1"].createInstance(Components.interfaces.nsIConverterInputStream);

		   fp.init(window, null, fp.modeOpen);
		   fp.defaultExtension = "txt";
		   fp.appendFilters(fp.filterText);

		   if (fp.show() != fp.returnCancel) {
			  try {
				 var input = {};
				 stream.init(fp.file, 0x01, 0444, null);
				 converter.init(stream, "UTF-8", 0, 0x0000);
				 converter.readString(stream.available(), input);
				 var linebreak = input.value.match(/(((\n+)|(\r+))+)/m)[1];
				 return input.value.split(linebreak);
			  } finally {
				 converter.close();
				 stream.close();
			  }
		   }
		   return null;
		}

		mkiosk_biblio.prototype.getAllSettings = function(isDefault) {
		   var prefservice = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
		   var prefs = (isDefault ? prefservice.getDefaultBranch("") : prefservice.getBranch("") );
		   var preflist = prefs.getChildList("coral.mkiosk_biblio.", {});

		   var aList = ["#IE Tab Plus Preferences"];
		   for (var i = 0 ; i < preflist.length ; i++) {
			  try {
				 var value = null;
				 switch (prefs.getPrefType(preflist[i])) {
				 case prefs.PREF_BOOL:
					value = prefs.getBoolPref(preflist[i]);
					break;
				 case prefs.PREF_INT:
					value = prefs.getIntPref(preflist[i]);
					break;
				 case prefs.PREF_STRING:
					value = prefs.getComplexValue(preflist[i], Components.interfaces.nsISupportsString).data;
					break;
				 }
				 aList.push(preflist[i] + "=" + value);
			  } catch (e) {}
		   }
		   return aList;
		}

		mkiosk_biblio.prototype.setAllSettings = function(aList) {
		   if (!aList) return;
		   if (aList.length == 0) return;
		   if (aList[0] != "#IE Tab Plus Preferences") return;

		   var prefservice = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
		   var prefs = prefservice.getBranch("");

		   var aPrefs = [];
		   for (var i = 1 ; i < aList.length ; i++){
			  var index = aList[i].indexOf("=");
			  if (index > 0){
				 var name = aList[i].substring(0, index);
				 var value = aList[i].substring(index+1, aList[i].length);
				 if (this.startsWith(name, "coral.mkiosk_biblio.")) aPrefs.push([name, value]);
			  }
		   }
		   for (var i = 0 ; i < aPrefs.length ; i++) {
			  try {
				 var name = aPrefs[i][0];
				 var value = aPrefs[i][1];
				 switch (prefs.getPrefType(name)) {
				 case prefs.PREF_BOOL:
					prefs.setBoolPref(name, /true/i.test(value));
					break;
				 case prefs.PREF_INT:
					prefs.setIntPref(name, value);
					break;
				 case prefs.PREF_STRING:
					if (value.indexOf('"') == 0) value = value.substring(1, value.length-1);
					var sString = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
					sString.data = value;
					prefs.setComplexValue(name, Components.interfaces.nsISupportsString, sString);
					break;
				 }
			  } catch (e) {}
		   }
		}

		mkiosk_biblio.prototype.exportSettings = function() {
		   var aList = this.getAllSettings();
		   if (aList) this.saveToFile(aList);
		}

		mkiosk_biblio.prototype.importSettings = function() {
		   var aList = this.loadFromFile();
		   if (aList) {
			  this.setAllSettings(aList);
			  this.initDialog();
			  this.updateInterface();
		   }
		}

		mkiosk_biblio.prototype.restoreDefault = function() {
			if (confirm(gmkiosk_biblio.GetLocalizedString("confirm_reset"))) {
				var aTemp = this.getAllSettings(false);
				var aDefault = this.getAllSettings(true);
				this.setAllSettings(aDefault);
				this.initDialog();
				this.setAllSettings(aTemp);
				this.updateApplyButton(true);
			}
		}

		mkiosk_biblio.prototype.importSettingsFrommkiosk_biblio = function() {
		   var ruleList = this.getPrefFilterListFromOldmkiosk_biblio();
		   if ( ruleList ) {
				for (var i = 0; i < ruleList.length; i++) {
					if (ruleList[i]) {
						this.addFilterRule('0,'+ruleList[i]);
					}
				}
			}
			else {
					alert(gmkiosk_biblio.GetLocalizedString("no_mkiosk_biblio_settings"));
			}
		}

		mkiosk_biblio.prototype.GetLocalizedString = function(name) {
			var s = "";
			try {
				var stringService = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
				var strings = stringService.createBundle("chrome://coralmkiosk_biblio/locale/global.properties");
				s = strings.GetStringFromName(name);
			}
			catch(e) {}
			return s;
		};

		mkiosk_biblio.prototype.isValidURL = function(url) {
			var b = false;
			try {
				const ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
				var uri = ios.newURI(url, null, null);
				b = true;		
			}
			catch (e) {}
			return b;
		}

		mkiosk_biblio.prototype.isValidDomainName = function(domainName) {
			return /^[0-9a-zA-Z]+[0-9a-zA-Z\.\_\-]*\.[0-9a-zA-Z\_\-]+$/.test(domainName);
		}

		mkiosk_biblio.prototype.getExtAppName = function(extAppPathName) {
			var result = gmkiosk_biblio.GetLocalizedString("default_ext_app_name");
			
			try {
				if ( extAppPathName.length > 0 ) {
					var wrk = Components.classes["@mozilla.org/windows-registry-key;1"].createInstance(Components.interfaces.nsIWindowsRegKey);
					wrk.open(wrk.ROOT_KEY_CURRENT_USER, "Software\\Microsoft\\Windows\\ShellNoRoam\\MUICache", wrk.ACCESS_READ);
					result = wrk.readStringValue(extAppPathName);
					wrk.close();
				}
				else {
					result = "Internet Explorer";
				}
			}
			catch(e) {
				// Components.utils.reportError(e.toString());
			}
			
			return result;
		}

		mkiosk_biblio.prototype.mlog = function(text) {
		  Components.classes["@mozilla.org/consoleservice;1"]
			.getService(Components.interfaces.nsIConsoleService)
			.logStringMessage("[IE Tab Plus] "+text);
		}

		mkiosk_biblio.prototype.getRegistryEntry = function(regRoot, regPath, regName) {
			var result = null;
			try {
			   if ("@mozilla.org/windows-registry-key;1" in Components.classes) {
				  var nsIWindowsRegKey = Components.classes["@mozilla.org/windows-registry-key;1"].getService(Components.interfaces.nsIWindowsRegKey);
				  var regRootKey = new Array(0x80000000, 0x80000005, 0x80000001, 0x80000002, 0x80000003);
				  nsIWindowsRegKey.open(regRootKey[regRoot], regPath, Components.interfaces.nsIWindowsRegKey.ACCESS_READ);
				  if (nsIWindowsRegKey.valueCount) {
					 result = nsIWindowsRegKey.readStringValue(regName);
				  }
				  nsIWindowsRegKey.close();
			   }
			} catch(e) {}
			
			return result;
		}

		//-----------------------------------------------------------------------------

		mkiosk_biblio.prototype.addEventListener = function(obj, type, listener) {
		   if (typeof(obj) == "string") obj = document.getElementById(obj);
		   if (obj) obj.addEventListener(type, listener, false);
		}
		mkiosk_biblio.prototype.removeEventListener = function(obj, type, listener) {
		   if (typeof(obj) == "string") obj = document.getElementById(obj);
		   if (obj) obj.removeEventListener(type, listener, false);
		}

		mkiosk_biblio.prototype.addEventListenerByTagName = function(tag, type, listener) {
		   var objs = document.getElementsByTagName(tag);
		   for (var i = 0; i < objs.length; i++) {
			  objs[i].addEventListener(type, listener, false);
		   }
		}
		mkiosk_biblio.prototype.removeEventListenerByTagName = function(tag, type, listener) {
		   var objs = document.getElementsByTagName(tag);
		   for (var i = 0; i < objs.length; i++) {
			  objs[i].removeEventListener(type, listener, false);
		   }
		}

		//-----------------------------------------------------------------------------

		mkiosk_biblio.prototype.hookCode = function(orgFunc, orgCode, myCode) {
		   try{ if (eval(orgFunc).toString() == eval(orgFunc + "=" + eval(orgFunc).toString().replace(orgCode, myCode))) throw orgFunc; }
		   catch(e){ /* Components.utils.reportError("Failed to hook function: "+orgFunc); */ }
		}

		mkiosk_biblio.prototype.hookAttr = function(parentNode, attrName, myFunc) {
		   if (typeof(parentNode) == "string") parentNode = document.getElementById(parentNode);
		   try { parentNode.setAttribute(attrName, myFunc + parentNode.getAttribute(attrName)); }catch(e){ Components.utils.reportError("Failed to hook attribute: "+attrName); }
		}

		mkiosk_biblio.prototype.hookProp = function(parentNode, propName, myGetter, mySetter) {
		   var oGetter = parentNode.__lookupGetter__(propName);
		   var oSetter = parentNode.__lookupSetter__(propName);
		   if (oGetter && myGetter) myGetter = oGetter.toString().replace(/{/, "{"+myGetter.toString().replace(/^.*{/,"").replace(/.*}$/,""));
		   if (oSetter && mySetter) mySetter = oSetter.toString().replace(/{/, "{"+mySetter.toString().replace(/^.*{/,"").replace(/.*}$/,""));
		   if (!myGetter) myGetter = oGetter;
		   if (!mySetter) mySetter = oSetter;
		   if (myGetter) try { eval('parentNode.__defineGetter__(propName, '+ myGetter.toString() +');'); }catch(e){ Components.utils.reportError("Failed to hook property Getter: "+propName); }
		   if (mySetter) try { eval('parentNode.__defineSetter__(propName, '+ mySetter.toString() +');'); }catch(e){ Components.utils.reportError("Failed to hook property Setter: "+propName); }
		}

		//-----------------------------------------------------------------------------

		mkiosk_biblio.prototype.trim = function(s) {
		   if (s) return s.replace(/^\s+/g,"").replace(/\s+$/g,""); else return "";
		}

		mkiosk_biblio.prototype.startsWith = function(s, prefix) {
		   if (s) return( (s.substring(0, prefix.length) == prefix) ); else return false;
		}

		mkiosk_biblio.prototype.endsWith = function(s, suffix) {
			if (s && (s.length > suffix.length)) {
				return (s.substring(s.length-suffix.length) == suffix);
			}
			else return false;
		}

		//-----------------------------------------------------------------------------

		mkiosk_biblio.prototype.getBoolPref = function(prefName, defval) {
		   var result = defval;
		   var prefservice = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
		   var prefs = prefservice.getBranch("");
		   if (prefs.getPrefType(prefName) == prefs.PREF_BOOL) {
			   try { result = prefs.getBoolPref(prefName); }catch(e){}
		   }
		   return(result);
		}

		mkiosk_biblio.prototype.getIntPref = function(prefName, defval) {
		   var result = defval;
		   var prefservice = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
		   var prefs = prefservice.getBranch("");
		   if (prefs.getPrefType(prefName) == prefs.PREF_INT) {
			   try { result = prefs.getIntPref(prefName); }catch(e){}
		   }
		   return(result);
		}

		mkiosk_biblio.prototype.getStrPref = function(prefName, defval) {
		   var result = defval;
		   var prefservice = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
		   var prefs = prefservice.getBranch("");
		   if (prefs.getPrefType(prefName) == prefs.PREF_STRING) {
			   try { result = prefs.getComplexValue(prefName, Components.interfaces.nsISupportsString).data; }catch(e){}
		   }
		   return(result);
		}

		//-----------------------------------------------------------------------------

		mkiosk_biblio.prototype.setBoolPref = function(prefName, value) {
		   var prefservice = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
		   var prefs = prefservice.getBranch("");
		   try { prefs.setBoolPref(prefName, value); } catch(e){}
		}

		mkiosk_biblio.prototype.setIntPref = function(prefName, value) {
		   var prefservice = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
		   var prefs = prefservice.getBranch("");
		   try { prefs.setIntPref(prefName, value); } catch(e){}
		}

		mkiosk_biblio.prototype.setStrPref = function(prefName, value) {
		   var prefservice = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);
		   var prefs = prefservice.getBranch("");
		   var sString = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
		   sString.data = value;
		   try { prefs.setComplexValue(prefName, Components.interfaces.nsISupportsString, sString); } catch(e){}
		}

		//-----------------------------------------------------------------------------

		mkiosk_biblio.prototype.getDefaultCharset = function(defval) {
		   var charset = this.getStrPref("coral.mkiosk_biblio.intl.charset.default", "");
		   if (charset.length) return charset;
			var gPrefs = Components.classes['@mozilla.org/preferences-service;1'].getService(Components.interfaces.nsIPrefBranch);
			if(gPrefs.prefHasUserValue("intl.charset.default")) {
			   return gPrefs.getCharPref("intl.charset.default");
			} else {
			   var strBundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
			   var intlMess = strBundle.createBundle("chrome://global-platform/locale/intl.properties");
			   try {
				  return intlMess.GetStringFromName("intl.charset.default");
			   } catch(e) {
			   return defval;
			  }
			}
		}

		mkiosk_biblio.prototype.queryDirectoryService = function(aPropName) {
			try {
				var dirService = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
				var file = dirService.get(aPropName, Components.interfaces.nsIFile);
				return file.path;
			} catch (e) {}
			
			return null;
		}

		mkiosk_biblio.prototype.convertToUTF8 = function(data, charset) {
		   try {
			  data = decodeURI(data);
		   }catch(e){
			  if (!charset) charset = gmkiosk_biblio.getDefaultCharset();
			  if (charset) {
				 var uc = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
				 try {
					uc.charset = charset;
					data = uc.ConvertToUnicode(unescape(data));
					data = decodeURI(data);
				 }catch(e){}
				 uc.Finish();
			  }
		   }
		   return data;
		}

		mkiosk_biblio.prototype.convertToASCII = function(data, charset) {
		   if (!charset) charset = gmkiosk_biblio.getDefaultCharset();
		   if (charset) {
			  var uc = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
			  uc.charset = charset;
			  try {
				 data = uc.ConvertFromUnicode(data);
			  }catch(e){
				 data = uc.ConvertToUnicode(unescape(data));
				 data = decodeURI(data);
				 data = uc.ConvertFromUnicode(data);
			  }
			  uc.Finish();
		   }
		   return data;
		}

		//-----------------------------------------------------------------------------

		mkiosk_biblio.prototype.getUrlDomain = function(url) {
			var r = "";
			if (url && !gmkiosk_biblio.startsWith(url, "about:")) {
				if (/^file:\/\/.*/.test(url)) r = url;
				else {
					try {
						const ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
						var uri = ios.newURI(url, null, null);
						uri.path = "";
						r = uri.spec;
					}
					catch (e) {}
				}
		   }
		   return r;
		}

		mkiosk_biblio.prototype.getUrlHost = function(url) {
		   if (url && !gmkiosk_biblio.startsWith(url, "about:")) {
			  if (/^file:\/\/.*/.test(url)) return url;
			  var matches = url.match(/^([A-Za-z]+:\/+)*([^\:^\/]+):?(\d*)(\/.*)*/);
			  if (matches) url = matches[2];
		   }
		   return url;
		}

		//-----------------------------------------------------------------------------

		mkiosk_biblio.prototype.isFirefox = function() {
			const FIREFOX_ID = "{ec8030f7-c20a-464f-9b0e-13a3a9e97384}";
			var appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
			return (appInfo.ID == FIREFOX_ID);
		}
		  
		mkiosk_biblio.prototype.isVersionOlderThan = function(v) {
			var appInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
			var versionChecker = Cc["@mozilla.org/xpcom/version-comparator;1"].getService(Ci.nsIVersionComparator);
			return (versionChecker.compare(appInfo.version, v) >= 0);
		}

		mkiosk_biblio.prototype.dumpObject = function(obj) {
			var s = obj.toString() + "\n";
			for (var name in obj) {
				s += name + " = " + eval("obj."+name) + "\n";
			}
			gmkiosk_biblio.mlog(s);
		}
//-----------------------------------------------------------------------------
function cmd_selectAll() {
	var tree = document.getElementById('rulesList');
	if (tree) {
		tree.view.selection.selectAll();
	}
}

function cmd_copyToClipboard() {
	var ruleList = document.getElementById('rulesList');
	if (ruleList) {
		var rules = document.getElementById('rulesListChilds');
		var list = [];
		if (ruleList.view.selection.count > 0) {
			for (var i=rules.childNodes.length-1 ; i>=0 ; i--) {
				if (ruleList.view.selection.isSelected(i))
					list.push(rules.childNodes[i].firstChild.firstChild.getAttribute('label'));
			}
		}

		var clipboardHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);
		clipboardHelper.copyString(list.toString());
	}
}

function cmd_pasteFromClipboard() {
	var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"].getService(Components.interfaces.nsIClipboard);
	var transferable = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
	transferable.addDataFlavor("text/unicode");

	try {
		clipboard.getData(transferable, clipboard.kGlobalClipboard);
	}
	catch (e) {
		return;
	}

	var data = {};
	transferable.getTransferData("text/unicode", data, {});

	try {
		data = data.value.QueryInterface(Components.interfaces.nsISupportsString).data;
	}
	catch (e) {
		return;
	}

	for each (var ruleStr in data.split(','))
	{
		gmkiosk_biblio.addFilterRule('0,'+ruleStr);
	}
}

function cmd_startEditing() {
	var ruleList = document.getElementById('rulesList');
	if (ruleList) {
		var rules = document.getElementById('rulesListChilds');
		if (ruleList.view.selection.count > 0) {
			for (var i=rules.childNodes.length-1 ; i>=0 ; i--) {
				if (ruleList.view.selection.isSelected(i)) {
					ruleList.startEditing(i, ruleList.columns[0]);
					break;
				}
			}
		}
	}
}

function cmd_moveRulesUp() {
	var ruleList = document.getElementById('rulesList');
	if (ruleList) {
		var rules = document.getElementById('rulesListChilds');
		var treeSelection = ruleList.view.selection;
		if (treeSelection.count > 0) {
			// insertBefore method will clear our selection, so we have to firstly record all our selections,
			// then use another loop to perform moving.
			var list = [];
			for (var i = 0; i < treeSelection.getRangeCount(); i++) {
				var start = {}, end = {};
				treeSelection.getRangeAt(i, start, end);
				for (var j = start.value; j <= end.value; j++) {
					list.push(j);
				}
			}
			for (var i = 0; i < list.length; i++) {
				var j = list[i];
				if ( j > 0 ) {
					rules.insertBefore(rules.childNodes[j], rules.childNodes[j-1]);
					ruleList.view.selection.toggleSelect(j-1);
				}
			}
		}
	}
}

function cmd_moveRulesDown() {
	var ruleList = document.getElementById('rulesList');
	if (ruleList) {
		var rules = document.getElementById('rulesListChilds');
		if (ruleList.view.selection.count > 0) {
			for (var i=rules.childNodes.length-1; i>=0 ; i--) {
				if (ruleList.view.selection.isSelected(i)) {
					// Moving rules down is relatively simpler, just call insertBefore will work
					if ( i < rules.childNodes.length-1 ) rules.insertBefore(rules.childNodes[i+1], rules.childNodes[i]);
				}
			}
		}
	}
}

function enableSelectedRule(enable) {
	var ruleList = document.getElementById('rulesList');
	if (ruleList) {
		var rules = document.getElementById('rulesListChilds');
		if (ruleList.view.selection.count > 0) {
			for (var i=rules.childNodes.length-1 ; i>=0 ; i--) {
				if (ruleList.view.selection.isSelected(i)) {
					rules.childNodes[i].firstChild.childNodes[1].setAttribute('value', enable);
				}
			}
		}
	}
}

var gmkiosk_biblio = new mkiosk_biblio();
